

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#pragma pack(1)
typedef struct _node_{
    struct _node_ * parent  ;
    struct _node_ * zero    ;
    struct _node_ * one     ;
    void * data             ;
    uint64_t        index   ;
}radix_node_t;

#pragma pack(1)
typedef struct _radix_s_{
    radix_node_t * root     ;
    uint64_t       node_num ;

}


#pragma pack(1)
typedef struct _radix_parms_s_{
    uint64_t        node_num_max   ;     /* The hash table length */
    uint16_t        radix_hash_len ;     /* Hash length like 32 or 16 bit */
    uint64_t        node_drop_num  ;     /* For LRA */
    radix_node_t    *object_pool   ;     /* Node object pool , if NULL use malloc */
    uint64_t        empty_index    ;
}


#define OBJ_POOL_HEADH \
    radix_node_t *  nodes           ;   \
    uint64_t        empty_index     ;   \
    uint64_t        obj_max         ;   \
    uint64_t        obj_last        ;   \
    uint64_t        obj_pool_size   ;   

#define OBJ_POOL_LOCK \
    pthread_mutex_t obj_mutex       ;   

#pragma pack(1)
typedef struct _object_pool_l_s{
    OBJ_POOL_HEADH                  
    OBJ_POOL_LOCK
}object_pool_t;





object_pool_t * dc_ini_obj_pool( uint64_t obj_max )
{
    object_pool_t *op = (object_pool_t *)malloc( sizeof( object_pool_t ));
    if ( op == ( object_pool_t *)NULL )
    {
        return (object_pool_t *)NULL ;
    }

    op->nodes = (radix_node_t *)malloc( sizeof( radix_node_t ) * obj_max );
    if( op->nodes == (radix_node_t *)NULL )
    {
        free(op);
        return (radix_node_t *)NULL;
    }
    op->nodes == (radix_node_t *)NULL ;

    op->empty_index = 0             ;       
    op->obj_max = obj_max           ;
    obj_last = obj_max              ;
    op->obj_pool_size = sizeof( radix_node_t ) * obj_max ;

    radix_node_t *  pnodes = op->nodes ;

    pnodes[obj_max - 1].data = (void *)NULL     ;
    pnodes[obj_max - 1].index = obj_max -1      ;
    int i = 0 ;
    for( ; i = obj_max - 2 ; i-- )
    {
        pnodes[i].data  = ( radix_node_t *)&pnodes[i+1] ;
        pnodes[i].index = i ; 
    }

    return op ;
}
 // object poll will grows when no spaces , as it to say 
 // when obj_last == 0 , index_level ++ 
 // nodes[index_level] be trated as object pool 


radix_node_t * dc_get_node( object_pool_t * op )
{
    if (op == (obj_pool_t *)NULL)
    {
        return (radix_node_t *)NULL ;
    }

    if (op->obj_last == 0 )
    {
        return (radix_node_t *)NULL ;
    }

    radix_node_t * ret = (radix_node_t *)NULL ;
    uint64_t    empty_index = op->empty_index ;
    ret = op->nodes[empty_index];
    op->empty_index = (radix_node_t * )(op->nodes[empty_index].data)->index     ;
    op->obj_last-- ;

    return (radix_node_t *)ret ;
}












